#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *Routine(void *args)
{
    pthread_detach(pthread_self()); // 线程分离，主线程不用回收
    std::cout << (char *)args << " run..." << std::endl;
    while (true)
    {
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond, &mutex); // 阻塞在这里，直到被唤醒
        std::cout << (char *)args << "活动..." << std::endl;
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, Routine, (void *)"thread-1");
    pthread_create(&t2, nullptr, Routine, (void *)"thread-2");
    pthread_create(&t3, nullptr, Routine, (void *)"thread-3");

    while (true)
    {
        getchar();
       // pthread_cond_signal(&cond);
       pthread_cond_broadcast(&cond);
    }
    return 0;
}

// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// void* Routine(void* args)
// {
//     pthread_mutex_lock(&mutex);
//     pthread_mutex_lock(&mutex);

//     pthread_exit(nullptr);
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, Routine, nullptr);

//     pthread_join(tid, nullptr);
//     return 0;
// }

// //全局锁或静态锁不用初始化和销毁
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// int tickets = 100;

// void *TicketGrabbing(void *args)
// {
//     std::string name = static_cast<char *>(args);
//     while (true)
//     {
//         //上锁，对抢票临界区进行保护
//         pthread_mutex_lock(&mutex);
//         if (tickets > 0)
//         {
//             usleep(10000);
//             std::cout << name << "get a ticket, left:" << --tickets << std::endl;
//             //解锁
//             pthread_mutex_unlock(&mutex);
//         }
//         else
//         {
//             pthread_mutex_unlock(&mutex);
//             break;
//         }
//     }
//     std::cout << name << "quit" << std::endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t t1, t2, t3, t4;
//     pthread_create(&t1, nullptr, TicketGrabbing, (void *)"thread-1");
//     pthread_create(&t2, nullptr, TicketGrabbing, (void *)"thread-2");
//     pthread_create(&t3, nullptr, TicketGrabbing, (void *)"thread-3");
//     pthread_create(&t4, nullptr, TicketGrabbing, (void *)"thread-4");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);
//     return 0;
// }

// int tickets = 100;
// void *TicketGrabbing(void *args)
// {
//     std::string name = static_cast<char *>(args);
//     while (true)
//     {
//         if (tickets > 0)
//         {
//             usleep(10000);
//             std::cout << name << "get a ticket, left:" << --tickets << std::endl;
//         }
//         else
//         {
//             break;
//         }
//     }
//     std::cout << name << "quit" << std::endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t t1, t2, t3, t4;
//     pthread_create(&t1, nullptr, TicketGrabbing, (void *)"thread-1");
//     pthread_create(&t2, nullptr, TicketGrabbing, (void *)"thread-2");
//     pthread_create(&t3, nullptr, TicketGrabbing, (void *)"thread-3");
//     pthread_create(&t4, nullptr, TicketGrabbing, (void *)"thread-4");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);
//     return 0;
// }

// int count = 0;

// void* Routine(void* args)
// {
//     while(true)
//     {
//         sleep(1);
//         count++;
//     }
//     pthread_exit((void*)0);
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, Routine, nullptr);
//     while(true)
//     {
//         std::cout<<"count:"<<count<<std::endl;
//         sleep(1);
//     }
//     pthread_join(tid, nullptr);
//     return 0;
// }